home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1998 April: Mac OS SDK / Dev.CD Apr 98 SDK2.toast / Development Kits (Disc 2) / QuickTime / Programming Stuff / Documentation / develop articles / develop Issue 20 / QTTextSample / TextMediaExample.c < prev    next >
Encoding:
Text File  |  1997-02-26  |  49.6 KB  |  1,918 lines  |  [TEXT/KAHL]

  1. // Text Media Sample Code
  2. //
  3. // sample to show how to do searches with text media, and how to use
  4. // a simple text proc to get the text (without the style info) out and
  5. // to display it in a window.
  6. //
  7. // This is something of a work in progress, it contains a few bugs, if you find
  8. // anthing that you feel needs fixing, or explaining, please let me know
  9. // AppleLink: NICKT
  10. //
  11. // 
  12. // Modification History:
  13. //
  14. //        5/16/94        nick    added text media stuff, repeat text in box below movie, uses TextBox
  15. //        5/17/94        nick    implement find dialog
  16. //         5/31/94        nick    implement textedit stuff to allow editing of the text track
  17. //        6/1/94        nick    clean up textedit stuff and allow user to edit the text track
  18. //        8/10/94        nick    support for styled text, bug fixes
  19. //        9/29/94        nick    support for core appleevents
  20. //        10/13/94    nick    cleaned up for release
  21. //                            fix up cut and paste for text edit commands
  22. //                            added TE edit menu
  23. //        10/14/94    nick    final clean up, move adjust menus to just before menukey or menuselect
  24. //                            
  25. //
  26. // to do:
  27. //        make the edit box scrollable, implement font menus, style and size mwnus for text
  28. //
  29. //    Copyright:    © 1992-4 by Apple Computer, Inc.
  30.  
  31. #include <FixMath.h>
  32.  
  33. #include "mtb.h"
  34. #include "aevt.h"
  35. #include "TextMediaExample.h"
  36. #include "QuickTimeUtils.h"
  37.  
  38. extern Boolean    gQuitFlag = false ;            // set to true when we want to quit
  39.  
  40. const        RGBColor    kWindowBGColor     = {0xFF00, 0xFF00, 0xFF00} ;    // grays made the caret yellow, ughh, need to investigate this
  41. const         RGBColor    kRGBBlack     = {0x0000, 0x0000, 0x0000} ;
  42. const         RGBColor     kRGBGray     = {0xAAAA, 0xAAAA, 0xAAAA} ;
  43. const         RGBColor    kRGBWhite     = {0xFFFF, 0xFFFF, 0xFFFF} ;
  44.  
  45. const        Rect        kDefaultWinRect ;
  46. const        short        kSlopMargin = 8 ;
  47.  
  48. Boolean        gDlgSearchBack = false ;
  49. Boolean        gDlgSearchWrap = false ;
  50. Str255        gDlgSearchText = "\p" ;
  51.  
  52. //---------------------------------------------------------------------
  53.  
  54. DocumentHandle        CreateDocumentHandle( WindowPtr    aWindow )
  55. {
  56.     DocumentHandle    theHandle ;
  57.     
  58.     theHandle = (DocumentHandle)NewHandle( sizeof(DocumentRecord)) ;
  59.     if( theHandle != nil ) {
  60.     
  61.         // make sure we init the doc record fields to sensible values.
  62.         
  63.         (**theHandle).myController = nil ;
  64.         (**theHandle).myTEH = nil ;
  65.         (**theHandle).myFindButton = nil ;            // this is the find button for this window
  66.         (**theHandle).myUpdateButton = nil ;        // allows the user to update the movie text track
  67.         (**theHandle).myMovieIsActive = true ;        // either the movie is or the te field is.
  68.         (**theHandle).myTextHasBeenModified = false ;
  69.         
  70.         // store a reference to the document record for this window 
  71.         // in the refcon field of this window.
  72.         SetWRefCon ( aWindow, (long)theHandle );
  73.  
  74.     }
  75.     
  76.     return    theHandle ;
  77. }
  78.  
  79. //---------------------------------------------------------------------
  80.  
  81. WindowPtr    CreateMovieWindow( Rect *aRect, Str255 theTitle ) 
  82. {
  83.     RGBColor            nattyGray = kWindowBGColor ;
  84.     GrafPtr                savedPort ;
  85.     WindowPtr            aWindow ;
  86.  
  87.     GetPort( &savedPort ) ;
  88.  
  89.     // create a window for the movie
  90.     if((aWindow = NewCWindow(nil, 
  91.                             aRect, 
  92.                             theTitle, 
  93.                             false, 
  94.                             noGrowDocProc, 
  95.                             (WindowPtr)-1, 
  96.                             true, 
  97.                             0 )) != nil )
  98.     {                        
  99.         // set our port to the newly created movie, make
  100.         // the content area gray.
  101.         SetPort( aWindow );
  102.         RGBBackColor( &nattyGray ) ;
  103.     }
  104.     
  105.     // restore current port
  106.     
  107.     SetPort( savedPort );
  108.     return aWindow ;
  109. }
  110.  
  111. //---------------------------------------------------------------------
  112.  
  113. MovieController    SetUpMovieWindowWithController( WindowPtr    aWindow, Movie aMovie ) 
  114. {
  115.     MovieController        aController;    // the controller for this movie
  116.     Rect                aRect ;            // bounding rect of the movie
  117.     GrafPtr                savedPort ;        // used to reset the current port
  118.     DocumentHandle        aDocHdl ;
  119.     short                movieWidth ;
  120.     short                movieHeight ;
  121.  
  122.     aDocHdl = (DocumentHandle)GetWRefCon( aWindow ) ;
  123.  
  124.     // save whatever the port was before we go in here
  125.     GetPort( &savedPort ) ;
  126.     
  127.     DoPrerollMovie( aMovie ) ;
  128.      
  129.      // sanity check
  130.     if( aMovie == nil )
  131.         CheckError( paramErr, "\pSetUpMovieWindowWithController was passed nil for aMovie") ;
  132.  
  133.      SetPort( (GrafPtr)aWindow ) ;
  134.      
  135.      // set the movies environment to the current
  136.     // port and gDevice (pass nil for defaults)
  137.     SetMovieGWorld( aMovie, nil, nil ) ;
  138.     
  139.     // Use the movie bounding rect to size the movie
  140.     GetMovieBox( aMovie, &aRect );    
  141.  
  142.     // lets make sure the movie bounds are reasonable
  143.     movieWidth = aRect.right - aRect.left ;
  144.     movieHeight = aRect.bottom - aRect.top ;
  145.     aRect.top = aRect.left = 0 ;
  146.     aRect.right = movieWidth ;
  147.     aRect.bottom = movieHeight ;
  148.  
  149.     OffsetRect( &aRect, kSlopMargin, kSlopMargin ) ;
  150.         
  151.     SetMovieBox( aMovie, &aRect );    
  152.  
  153.     // create a movie controller for the movie
  154.     aController = NewMovieController (aMovie, &aRect, 0L | mcTopLeftMovie | mcWithBadge );
  155.     
  156.     // should have some error handling here
  157.     if (aController == nil) 
  158.         ExitToShell();
  159.     else
  160.         (**aDocHdl).myController = aController ;
  161.     
  162.     SetPort( savedPort ) ;
  163.     return aController ;
  164. }    
  165.  
  166. //---------------------------------------------------------------------
  167.  
  168. OSErr SetMovieTextHandler( WindowPtr aWindow )
  169. {
  170.     MediaHandler            aMediaHandler ;
  171.     MovieController            aController ;
  172.     Movie                    aMovie ;
  173.     Track                    aTrack ;
  174.     DocumentHandle            aDocHdl ;
  175.  
  176.     aDocHdl = (DocumentHandle)GetWRefCon( aWindow ) ;
  177.     aController = (**aDocHdl).myController ;
  178.  
  179.     if( aController != nil ) {
  180.         aMovie = MCGetMovie( aController ) ;
  181.     }
  182.     else {
  183.         CheckError( -1, "\pCouldn't get movie controller") ;
  184.     }
  185.     // set the text handling procedure - we only want 
  186.     // to do this is there is not a text track in the movie
  187.     
  188.     if((aTrack = GetFirstTrackOfType( aMovie, TextMediaType )) != nil )
  189.     {
  190.         // we need the duration of the text track
  191.         // load the text track into ram
  192.         LoadTrackIntoRam( aTrack, 0L, GetTrackDuration( aTrack ), 0L ) ;
  193.  
  194.         aMediaHandler = GetMediaHandler( GetTrackMedia( aTrack ) ) ;
  195.         if( aMediaHandler != nil ) {
  196.             SetTextProc( aMediaHandler, NewTextMediaProc(MyTextProc), (long)aWindow ) ;
  197.         }
  198.     }
  199.     return GetMoviesError() ;
  200. }
  201.  
  202. //---------------------------------------------------------------------
  203.  
  204. OSErr    AddTEAndControl( WindowPtr    aWindow ) 
  205. {
  206.     Rect                    aRect ;
  207.     Rect                    controlRect ;
  208.     MovieController            aController ;
  209.     Movie                    aMovie ;
  210.     GrafPtr                    savedPort ;
  211.     ControlHandle            aControl ;
  212.     DocumentHandle            aDocHdl ;
  213.  
  214.     short                    movieWindowWidth ;
  215.     short                    movieWindowLength ;
  216.     
  217.     aDocHdl = (DocumentHandle)GetWRefCon( aWindow ) ;
  218.     aController = (**aDocHdl).myController ;
  219.  
  220.     // Get the rect for the movie controller (includes the movie)
  221.     
  222.     if( aController != nil ) {
  223.         // get the bounding rect of the movie plus the controller
  224.         CheckError( MCGetControllerBoundsRect(aController, &aRect), "\pMCGetControllerBoundsRect") ;
  225.     }
  226.     else {
  227.         CheckError( -1, "\pCouldn't get movie controller") ;
  228.     }
  229.     
  230.     InsetRect ( &aRect, -kSlopMargin, -kSlopMargin );
  231.     
  232.     GetPort( &savedPort ) ;
  233.     SetPort( aWindow ) ;
  234.  
  235.  
  236.     // allow 125 pixels for us to display the text, the update text btn, and the find button
  237.     aRect.bottom += 125 ;
  238.  
  239.     // we use these elsewhere so calculate this stuff now
  240.     movieWindowWidth = aRect.right - aRect.left ;
  241.     movieWindowLength = aRect.bottom - aRect.top ;
  242.  
  243.     SizeWindow (aWindow, movieWindowWidth, movieWindowLength, true);
  244.                      
  245.     // create a TE record
  246.     {
  247.         short    h, v ;
  248.         Rect    theRect ;
  249.         
  250.         // get the bounds of the window
  251.         theRect = ((GrafPtr)aWindow)->portRect ;
  252.     
  253.         // we will always want 115 pixels from the bottom of the window
  254.         v = theRect.bottom - 115 ;
  255.         h = theRect.right - theRect.left ;
  256.     
  257.         // get the bounds of the box to draw in
  258.         theRect.top = v ;
  259.         theRect.bottom = v + 25 ;
  260.         theRect.left = 0 ;
  261.         theRect.right = h  ;
  262.         
  263.         InsetRect( &theRect, kSlopMargin, 0 ) ;
  264.         
  265.         
  266.         (**aDocHdl).myTEH = TEStyleNew( &theRect, &theRect ) ;
  267.     }
  268.                      
  269.     // create the button for updating the text
  270.     
  271.     if(( aControl = GetNewControl( 130, aWindow )) == nil )
  272.         ExitToShell() ;
  273.         
  274.     controlRect = (**aControl).contrlRect ;
  275.     
  276.     {
  277.         short    h ;
  278.         short    v ;
  279.         
  280.         h = (aRect.right - aRect.left) - (controlRect.right - controlRect.left) - 16 ;
  281.         v = (aRect.bottom - aRect.top) - (controlRect.bottom - controlRect.top) - 16 ;
  282.     
  283.         // locate the control so that its bottom right corner is 16 x 16 pixels from
  284.         // the bottom r.h. corner of the window.  This is a good technique to use
  285.         // as it would allow easy localization of the control title in the resource,
  286.         // which may alter the size of the control.
  287.         
  288.         MoveControl( aControl, h, v ) ;
  289.         
  290.         // store the reference to the control in the document record
  291.         (**aDocHdl).myUpdateButton = aControl ;
  292.     }
  293.     
  294.     // create the button to do the searches
  295.     
  296.     if(( aControl = GetNewControl( 128, aWindow )) == nil )
  297.         ExitToShell() ;
  298.         
  299.     controlRect = (**aControl).contrlRect ;
  300.     
  301.     {
  302.         short    h ;
  303.         short    v ;
  304.         
  305.         h = (aRect.right - aRect.left) - (controlRect.right - controlRect.left) - 16 ;
  306.         v = (aRect.bottom - aRect.top) - (controlRect.bottom - controlRect.top) - (16 + 35);
  307.     
  308.         // locate the control so that its bottom right corner is 16 x (16 + 35) pixels from
  309.         // the bottom r.h. corner of the window.  This is a good technique to use
  310.         // as it would allow easy localization of the control title in the resource,
  311.         // which may alter the size of the control.
  312.         
  313.         MoveControl( aControl, h, v ) ;
  314.         
  315.         // store the reference to the control in the document record
  316.         (**aDocHdl).myFindButton = aControl ;
  317.     }
  318.     
  319.     // move the window to {50,50} on the main device and show it             
  320.     MoveWindow ( aWindow, 50, 50, true );
  321.     
  322.     // the next command ensures the window is aligned to a longword
  323.     // boundary, which will ensure premium performance for playback
  324.     // *** need to update the drag code ***    
  325.     AlignWindow( aWindow, false, &aRect, nil ) ;             
  326.  
  327.     SetPort( savedPort ) ;
  328.  
  329. }
  330.  
  331. //---------------------------------------------------------------------
  332.  
  333. void    DoCreateMovieWindow( Movie aMovie ) 
  334. {
  335.     Rect                         aRect = kDefaultWinRect ;
  336.     Rect                        controlRect ;                 // for the push button control
  337.     WindowPtr                     aWindow;
  338.     Track                        aTrack ;
  339.     ControlHandle                aControl ;
  340.     MovieController                aController ;
  341.     DocumentHandle                theDocHandle ;
  342.     GrafPtr                        savedPort ;
  343.         
  344.         
  345.     GetPort( &savedPort ) ;
  346.     
  347.     // create the window
  348.     aWindow = CreateMovieWindow( &aRect, "\pA Movie" ) ;
  349.     SetPort( (GrafPtr)aWindow ) ;
  350.     
  351.     if( aWindow == nil ) 
  352.         CheckError( -1, "\pCouldn't create window") ;
  353.     
  354.     // set up our document handle in the refcon field of the window
  355.     theDocHandle = CreateDocumentHandle( aWindow ) ;
  356.     if( theDocHandle == nil ) 
  357.         CheckError( MemError(), "\pCouldn't allocate memory") ;
  358.         
  359.     
  360.     // set up the movie for the window
  361.     aController = SetUpMovieWindowWithController( aWindow, aMovie ) ;
  362.     
  363.     // set up the text handler proc for the movie
  364.     CheckError( SetMovieTextHandler( aWindow ), "\pCouldn't set the text handler for the movie window") ;
  365.         
  366.     // size the window for the movie and add the TE record and the controls
  367.     AddTEAndControl( aWindow ) ;    
  368.     
  369.     // finally show the window.
  370.     ShowWindow ( aWindow );
  371.  
  372.     // 
  373.     InvalRect( &((GrafPtr)aWindow)->portRect ) ;
  374.     
  375.     // set up the edit menu
  376.     MCEnableEditing( aController, true ) ;
  377.  
  378.     SetPort( savedPort ) ;
  379.  
  380. }
  381.  
  382.  
  383. //---------------------------------------------------------------------
  384.  
  385. void    DoDestroyMovieWindow( WindowPtr aWindow )
  386. {
  387.     Movie                aMovie ;
  388.     MovieController        aController ;
  389.     DocumentHandle        aDocHdl ;
  390.     
  391.     aDocHdl = (DocumentHandle)GetWRefCon( aWindow ) ;
  392.     aController = (**aDocHdl).myController ;
  393.         
  394.     if( aController != nil ) {
  395.         aMovie = MCGetMovie( aController ) ;
  396.         if( aMovie != nil ) {
  397.             DisposeMovie (aMovie);
  398.         }
  399.         DisposeMovieController (aController);
  400.     }
  401.     
  402.     DisposeWindow(aWindow);
  403. }
  404.  
  405. //---------------------------------------------------------------------
  406.  
  407. void    DoUpdateText( WindowPtr whichWindow, Point theMouse, ControlHandle aControl ) 
  408. {
  409.     Track            aTrack ;
  410.     MediaHandler    aMediaHandler ;
  411.     Movie            aMovie ;
  412.     OSErr            theErr ;
  413.     DocumentHandle    aDocHdl;
  414.     MovieController    aController ;
  415.     GrafPtr            savedPort ;
  416.     
  417.     GetPort( &savedPort ) ;
  418.     SetPort( (GrafPtr)whichWindow ) ;
  419.     
  420.     // update the text track for the movie.
  421.     aDocHdl = (DocumentHandle)GetWRefCon( whichWindow ) ;
  422.     aController = (**aDocHdl).myController ;
  423.     
  424.     aMovie =     MCGetMovie(aController ) ;
  425.     
  426.     if( TrackControl(aControl, theMouse, nil ) != 0 ) {
  427.  
  428.         // get the text media track
  429.         if((aTrack = GetFirstTrackOfType( aMovie, TextMediaType )) != nil )
  430.         {
  431.             TimeValue        currentTime ;
  432.             TimeValue        interestingTime ;
  433.             TimeValue        theDuration ;
  434.             
  435.             TEHandle        aTEH ;
  436.             Media            aMedia ;
  437.             
  438.             CheckError( GetMoviesError(), "\pfailed after GetFirstTrackOfType");
  439.             aMedia =  GetTrackMedia( aTrack ) ;
  440.             aMediaHandler = GetMediaHandler( aMedia ) ;
  441.             
  442.             CheckError( GetMoviesError(), "\pfailed after GetMediaHandler");
  443.     
  444.             if( aMediaHandler != nil ) {
  445.                 
  446.                 Fixed            width ;
  447.                 Fixed            height ;
  448.                 Rect            trackBounds = {0, 0, 0, 0};    
  449.                 TimeValue        sampleTime ;        
  450.                 
  451.                 TimeValue        mediaSampleDuration ;
  452.                 TimeValue        mediaSampleStartTime ;
  453.                 TimeValue        mediaCurrentTime ;
  454.                 long            mediaSampleIndex ;
  455.  
  456.                 // get a handle to the text
  457.                 aTEH = (**aDocHdl).myTEH ;
  458.             
  459.                 // get the current movie time
  460.                 currentTime = GetMovieTime( aMovie, nil ) ;
  461.                 if( currentTime < 0 ) 
  462.                     CheckError( -1, "\pthis is an empty edit") ;
  463.                 
  464.                 // we need to find the start and duration for this media sample
  465.                 // first get the time in media time of the current sample
  466.                 
  467.                 mediaCurrentTime = TrackTimeToMediaTime( currentTime, aTrack ) ;
  468.                 
  469.                 // then get detailed information about the start and duration 
  470.                 // of the current sample, this is used later
  471.                 
  472.                 MediaTimeToSampleNum (    aMedia, 
  473.                                         mediaCurrentTime, 
  474.                                         &mediaSampleIndex, 
  475.                                         &mediaSampleStartTime,
  476.                                         &mediaSampleDuration);
  477.                                         
  478.                 //  look back and find where this text starts
  479.                 GetTrackNextInterestingTime( aTrack, nextTimeEdgeOK | nextTimeMediaSample, currentTime, 
  480.                                     -kFix1, &interestingTime, nil  ) ;
  481.                 
  482.                 currentTime = interestingTime ;
  483.                             
  484.                 GetTrackNextInterestingTime( aTrack, nextTimeEdgeOK | nextTimeMediaSample, currentTime, 
  485.                                     kFix1, &interestingTime, &theDuration ) ;
  486.                                     
  487.                 // tell the media that we are about to edit stuff
  488.                 theErr = BeginMediaEdits( aMedia ) ;
  489.                 if( theErr != noErr ) 
  490.                     return ;
  491.                         
  492.                 // delete whatever was there before            
  493.                 theErr = DeleteTrackSegment( aTrack, interestingTime, theDuration ) ;
  494.                 if( theErr != noErr ) 
  495.                     return ;
  496.                     
  497.                 // get the track bounds
  498.                 GetTrackDimensions( aTrack, &width, &height ) ;
  499.                 trackBounds.right = Fix2Long ( width );
  500.                 trackBounds.bottom = Fix2Long ( height );    
  501.  
  502.                 
  503.                 // and write out the new data to the media
  504.                 theErr = AddTESample(     aMediaHandler, 
  505.                                         aTEH, 
  506.                                         &((CGrafPtr)(**aTEH).inPort)->rgbBkColor, 
  507.                                         (**aTEH).just,                // use the justification from the TE record
  508.                                         &trackBounds, 
  509.                                         dfClipToTextBox, 
  510.                                         0, 
  511.                                         0, 
  512.                                         0, 
  513.                                         nil, 
  514.                                         mediaSampleDuration, 
  515.                                         &sampleTime) ;
  516.                                         
  517.                 if( theErr != noErr ) 
  518.                     return ;
  519.                     
  520.                 // insert the new media into the track
  521.                 theErr = InsertMediaIntoTrack(    aTrack, 
  522.                                                 interestingTime, 
  523.                                                 sampleTime, 
  524.                                                 mediaSampleDuration, 
  525.                                                 kFix1) ;
  526.                 
  527.                 theErr = EndMediaEdits( aMedia ) ;
  528.                 if( theErr != noErr ) 
  529.                     return ;
  530.             }
  531.             
  532.             InvalRect( &((GrafPtr)whichWindow)->portRect );        
  533.         }
  534.     }
  535.  
  536.     SetPort( savedPort ) ;
  537.     return ;    
  538. }
  539.  
  540.  
  541. //---------------------------------------------------------------------
  542.  
  543. void    HandleContentClick( WindowPtr whichWindow, EventRecord *theEvent )
  544. {
  545.     GrafPtr            oldPort ;
  546.     Boolean            handled = false;
  547.     DocumentHandle    aDocHdl ;
  548.     TEHandle        myTEHdl ;
  549.     Boolean            shiftDown = false ;
  550.     short            controlPart ;
  551.     ControlHandle    aControl ;
  552.     MovieController    aController ;
  553.     Boolean            isMyMovieActive ;
  554.     Boolean            savedActive ;
  555.     
  556.     ControlHandle    findBtn ;
  557.     ControlHandle    updateBtn ;
  558.     
  559.     GetPort(&oldPort ) ;    
  560.     SetPort( whichWindow );
  561.     
  562.     aDocHdl = (DocumentHandle)GetWRefCon( whichWindow ) ;
  563.     
  564.     if( aDocHdl == nil )
  565.         return ;
  566.         
  567.     findBtn = (**aDocHdl).myFindButton ;
  568.     updateBtn = (**aDocHdl).myUpdateButton;
  569.     
  570.     if( whichWindow != FrontWindow() )
  571.         SelectWindow ( whichWindow );
  572.  
  573.     GlobalToLocal( &theEvent->where ) ;
  574.     // did we click on the control?
  575.     controlPart = FindControl( theEvent->where, whichWindow, &aControl ) ;
  576.     switch( controlPart ) {
  577.         case inButton: 
  578.             if( aControl == findBtn ) {
  579.                 DoFindDialog( whichWindow, theEvent->where, aControl) ;
  580.                 handled = true ;
  581.             }
  582.             else if( aControl == updateBtn ) {
  583.                 DoUpdateText( whichWindow, theEvent->where, aControl) ;
  584.                 handled = true ;
  585.             }
  586.             break ;
  587.     }
  588.     
  589.     if( !handled )
  590.     {
  591.  
  592.         if( aDocHdl != nil ) {
  593.         
  594.             Rect            theRect ;
  595.             
  596.             // set up for hit testing
  597.             myTEHdl         = (**aDocHdl).myTEH ;
  598.             aController     = (**aDocHdl).myController ;
  599.             savedActive = isMyMovieActive = (**aDocHdl).myMovieIsActive ;
  600.             
  601.             if(myTEHdl == nil || aController == nil )
  602.                 return ;
  603.             
  604.             theRect = (**myTEHdl).viewRect ;
  605.             
  606.             // if the TE field is not already active, make it so
  607.             if( PtInRect( theEvent->where, &theRect ) ) {
  608.             
  609.                 (**aDocHdl).myMovieIsActive = false ;
  610.                 
  611.                 // if the movie was playing, make it stop
  612.                 MCDoAction( aController, mcActionPlay, nil ) ;
  613.             }
  614.             
  615.             // check to see if we clicked in the movie
  616.             // if the movie is not active make it so
  617.             // otherwise see if the click was in the TEField
  618.             
  619.             if(!isMyMovieActive) {
  620.                 if(IsPointInMovieController( aController, whichWindow, theEvent->where)) { ;
  621.                     (**aDocHdl).myMovieIsActive = true ;
  622.                 }
  623.                 else {
  624.                     if( PtInRect( theEvent->where, &theRect ) ) {
  625.  
  626.                         // if the movie is not active, let te process it
  627.                         TEClick(theEvent->where, theEvent->modifiers & shiftKey, myTEHdl) ;
  628.                     }
  629.                 }
  630.             }
  631.         }
  632.     }
  633.     
  634.     if(whichWindow == FrontWindow()) {
  635.         DoSelectActive( whichWindow ) ;
  636.     }
  637.  
  638.     // the update event handler handles toggling the
  639.     // highlight around the active area, this can be
  640.     // either the movie active or the textedit field
  641.  
  642.     if(    savedActive != (**aDocHdl).myMovieIsActive ) 
  643.         InvalRect( &((GrafPtr)whichWindow)->portRect ) ;
  644.  
  645.     SetPort( oldPort ) ;
  646. }
  647.  
  648. //---------------------------------------------------------------------
  649.  
  650. void    MyDoIdle( WindowPtr whichWindow ) 
  651. {
  652.     GrafPtr                oldPort ;
  653.     DocumentHandle        aDocHdl ;
  654.     TEHandle            myTEHdl ;
  655.     
  656.     GetPort(&oldPort ) ;    
  657.     SetPort( whichWindow );
  658.     
  659.     // did we click in the TE field
  660.     aDocHdl = (DocumentHandle)GetWRefCon( whichWindow ) ;
  661.     if( aDocHdl != nil ) {
  662.         myTEHdl = (**aDocHdl).myTEH ;
  663.         if( myTEHdl != nil ) {
  664.             TEIdle( myTEHdl ) ;
  665.         }
  666.     }
  667.  
  668.     SetPort( oldPort ) ;
  669.  
  670. }
  671.  
  672. //---------------------------------------------------------------------
  673.  
  674. void    DoActivateWindow( WindowPtr    whichWindow, Boolean becomingActive) 
  675. {
  676.     DocumentHandle        aDocHdl ;            // our document record is stuffed in the window refcon
  677.     ControlHandle        updateControlHandle,
  678.                         findControlHandle ;    // this is the find button
  679.     TEHandle            myTEH ;
  680.     MovieController        aController ;
  681.     GrafPtr                savedPort ;
  682.  
  683.     GetPort(&savedPort) ;
  684.     SetPort((GrafPtr)whichWindow) ;
  685.     
  686.     aDocHdl = (DocumentHandle)GetWRefCon(whichWindow) ;
  687.     if( aDocHdl != nil)
  688.     {        
  689.         findControlHandle     = (**aDocHdl).myFindButton ;
  690.         updateControlHandle = (**aDocHdl).myUpdateButton ;
  691.         myTEH             = (**aDocHdl).myTEH ;
  692.         aController     = (**aDocHdl).myController ;
  693.         
  694.         if( findControlHandle != nil && myTEH != nil)
  695.         {            
  696.             if( becomingActive ) {
  697.                 HiliteControl( findControlHandle, 0 ) ;
  698.  
  699.                 if( (**aDocHdl).myTextHasBeenModified )
  700.                     HiliteControl( updateControlHandle, 0 ) ;
  701.                 else
  702.                     HiliteControl( updateControlHandle, 255 ) ;
  703.  
  704.                 DoSelectActive( whichWindow ) ;
  705.                 AdornWindow( whichWindow, &kRGBBlack ) ;
  706.             }
  707.             else {
  708.                 Rect aFramingRect = (**myTEH).viewRect ;
  709.     
  710.                 HiliteControl( updateControlHandle, 255 ) ;
  711.                 HiliteControl( findControlHandle, 255 ) ;
  712.                 AdornWindow( whichWindow, &kRGBGray ) ;
  713.                 MCActivate( aController, whichWindow, false ) ;
  714.                 TEDeactivate( myTEH );
  715.         
  716.                 InvalRect( &aFramingRect ) ;
  717.             }
  718.         }
  719.     }
  720.  
  721.     SetPort(savedPort) ;
  722. }
  723.  
  724. void DoSelectActive( WindowPtr whichWindow ) 
  725. {
  726.     
  727.     // make sure that the movie and the text edit field are activated in 
  728.     // an appropriate manner.  We may either have the movie or the 
  729.     // text edit field selected, if the TE is selected make sure we "do the 
  730.     // right thing", if it is the movie make sure the controller is active.
  731.     DocumentHandle        aDocHdl ;
  732.     Boolean                movieIsActive ;
  733.     TEHandle            aTEH ;
  734.     MovieController        aController ;
  735.     
  736.     if( (aDocHdl = (DocumentHandle)GetWRefCon(whichWindow)) == nil)
  737.         return ;
  738.         
  739.     aTEH             = (**aDocHdl).myTEH ;
  740.     movieIsActive     = (**aDocHdl).myMovieIsActive ;
  741.     aController     = (**aDocHdl).myController ;
  742.     
  743.     if(  aTEH == nil || aController == nil)
  744.         return ;
  745.  
  746.      if( movieIsActive ) {
  747.         Rect aFramingRect = (**aTEH).viewRect ;
  748.  
  749.         MCActivate( aController, whichWindow, true ) ;
  750.         MCDoAction( aController, mcActionSetKeysEnabled, (void *)true) ;
  751.         TEDeactivate( aTEH );
  752.  
  753.         InvalRect( &aFramingRect ) ;
  754.     }
  755.     else {
  756.         MCActivate( aController, whichWindow, false ) ;
  757.         MCDoAction( aController, mcActionSetKeysEnabled, (void *)false) ;
  758.         TEActivate( aTEH ) ;
  759.     }
  760.     
  761.  
  762. }
  763.  
  764. //---------------------------------------------------------------------
  765. // AdornWindow assumes the port is set correctly...
  766. void    AdornWindow( WindowPtr whichWindow, const RGBColor *adornerColor )
  767. {
  768.     DocumentHandle        aDocHdl ;
  769.     Boolean                movieIsActive ;
  770.     TEHandle            aTEH ;
  771.     MovieController        aController ;
  772.     Rect                aFramingRect ;
  773.     RGBColor             color ;
  774.  
  775.     // get the foreground color
  776.     GetForeColor(&color);
  777.     
  778.     if( (aDocHdl = (DocumentHandle)GetWRefCon(whichWindow)) == nil)
  779.         return ;
  780.  
  781.     if( (**aDocHdl).myMovieIsActive ) {
  782.  
  783.         if(( aController = (**aDocHdl).myController) == nil)
  784.             return ;
  785.         
  786.         // get the movie bounding box & adorn it
  787.         MCGetControllerBoundsRect( aController, &aFramingRect ) ;
  788.         InsetRect( &aFramingRect, -6, -6 ) ;
  789.         PenSize( 2, 2 ) ;
  790.         RGBForeColor( adornerColor ) ;
  791.         FrameRect( &aFramingRect ) ;
  792.         PenNormal() ;
  793.         
  794.     }
  795.     else {
  796.     
  797.         if(( aTEH = (**aDocHdl).myTEH) == nil )
  798.             return ;
  799.         
  800.         // adorn the TERec, the user will know it is inactive, 
  801.         // because the caret is inactive.
  802.         aFramingRect = (**aTEH).viewRect ;
  803.         InsetRect( &aFramingRect, -2, -2 ) ;
  804.         PenSize( 1, 1 ) ;
  805.         GetForeColor(&color);
  806.         RGBForeColor( adornerColor ) ;
  807.         FrameRect( &aFramingRect ) ;
  808.         PenNormal() ;
  809.  
  810.     }
  811.  
  812.     // restore the foreground color
  813.     RGBForeColor(&color);
  814. }
  815.  
  816.  
  817. //---------------------------------------------------------------------
  818.  
  819. void    DoUpdateWindow( WindowPtr whichWindow )
  820. {
  821.     GrafPtr            savedPort ;
  822.     ControlHandle    theUpdateControl = (**((DocumentHandle)GetWRefCon(whichWindow))).myUpdateButton ;
  823.     
  824.     GetPort(&savedPort ) ;    
  825.     SetPort( whichWindow );
  826.  
  827.     BeginUpdate (whichWindow);
  828.     EraseRgn( whichWindow->visRgn ) ;
  829.  
  830.     // check to see if the update control should be active
  831.     if( (**((DocumentHandle)GetWRefCon(whichWindow))).myTextHasBeenModified )
  832.         HiliteControl( theUpdateControl, 0 ) ;
  833.     else
  834.         HiliteControl( theUpdateControl, 255 ) ;
  835.     
  836.     // draw the controls
  837.     DrawControls( whichWindow ) ;
  838.     
  839.     // draw the current text
  840.     DoDrawCurrentText( whichWindow ) ;
  841.     
  842.     // finally adorn the selection, we may either have the movie or the 
  843.     // text edit field selected, frame the selection, if it is the movie
  844.     // make sure the controller is active.
  845.     
  846.     AdornWindow( whichWindow, &kRGBBlack ) ;
  847.  
  848.     EndUpdate (whichWindow);
  849.     SetPort( savedPort ) ;
  850.  
  851. }
  852.  
  853. //---------------------------------------------------------------------
  854.  
  855. void MainEventLoop( void ) 
  856. {
  857.     OSErr                         err;
  858.     EventRecord                 theEvent;
  859.     WindowPtr                     whichWindow, theWindow;
  860.     short                         part;
  861.     short                        controlPart ;
  862.     ControlHandle                aControl ;
  863.     Boolean                        wasMovieEvent ;
  864.     MovieController                aController ;
  865.     Point                        aPoint = {100, 100};
  866.     Rect                         refreshArea ;
  867.     Rect                         screenRect ;
  868.     GrafPtr                        oldPort ;
  869.     
  870.     DocumentHandle                aDocHdl ;
  871.     Boolean                        myMovieIsActive ;
  872.  
  873.     
  874.     // use this in calls to MCDoAction
  875.     long                        myMCActionParams ;
  876.  
  877.     while (!gQuitFlag) {
  878.  
  879.         WaitNextEvent(everyEvent, &theEvent, 0, nil );
  880.  
  881.         wasMovieEvent = false ;
  882.         
  883.         // make sure we have an active front window
  884.         if((theWindow = FrontWindow()) != nil) 
  885.         {
  886.             // let the movie controller deal with the edit menu
  887.             aDocHdl = (DocumentHandle)GetWRefCon( theWindow ) ;
  888.             if( aDocHdl != nil ) 
  889.             {
  890.                 MovieController    aController = (**aDocHdl).myController ;
  891.                 
  892.                 myMovieIsActive = (**aDocHdl).myMovieIsActive ;
  893.  
  894.                 if( aController != nil ) 
  895.                 {
  896.                     // The edit menu - let the movie controller setting it up
  897.                     MenuHandle editMenu = GetMHandle ( mEdit ) ;
  898.                     MCSetUpEditMenu(aController, theEvent.modifiers, editMenu ) ;
  899.                 }
  900.             }
  901.             
  902.             // if the event is a mousedown and the movies is not active in the front
  903.             // window we want to do our "normal" mouseDown handling and make the movie
  904.             // active.
  905.             //
  906.             // the next statement looks a little wierd, what we are actually saying here is 
  907.             //
  908.             // "if the following is NOT true:
  909.             //
  910.             // the event is a mounse down AND the current movie is not active (i.e. the
  911.             // textEdit field is active - this is an either/or situation)
  912.             // 
  913.             // then
  914.             //
  915.             // let the movie controller handle it
  916.             //
  917.             // otherwise
  918.             //
  919.             // let it fall thru to the main event loop and let the mouse down handler 
  920.             // deal with it.
  921.             //
  922.             
  923.             if( !(theEvent.what == mouseDown && !myMovieIsActive))
  924.             {
  925.                 for( theWindow = FrontWindow(); theWindow != nil ; theWindow = (WindowPtr)((WindowPeek)theWindow)->nextWindow)
  926.                 {        
  927.                     // get the movie associated with the window
  928.                     if(( aDocHdl = (DocumentHandle)GetWRefCon( theWindow )) != nil) {
  929.                         aController = (**aDocHdl).myController ;
  930.             
  931.                         
  932.                         // check we have a valid controller, and 
  933.                         // if so, see if the controller can handle
  934.                         // this event
  935.                         
  936.                         if( aController != nil ) {
  937.                             
  938.                             wasMovieEvent = MCIsPlayerEvent(aController, &theEvent) ;
  939.                         }
  940.                     }
  941.                 }
  942.             }
  943.         }
  944.         
  945.                 
  946.         // if the controller didn't or couldn't handle it
  947.         // we need to handle it in the main event loop.
  948.             
  949.         if (!wasMovieEvent) {
  950.         
  951.             switch (theEvent.what) {
  952.             
  953.                 case nullEvent:
  954.                     if(( whichWindow = FrontWindow()) != nil ) 
  955.                         MyDoIdle( whichWindow ) ;
  956.                     break ;
  957.  
  958.                 case mouseDown:
  959.                     
  960.                     part = FindWindow (theEvent.where, &whichWindow);
  961.                                                         
  962.                     switch (part) {
  963.                     
  964.                         case inMenuBar: 
  965.                             AdjustMenus() ;
  966.                             HandleMenuCommand(MenuSelect(theEvent.where));
  967.                             break;
  968.                                                         
  969.                         case inDrag:
  970.                             {
  971.                                 Rect             r;
  972.                                 Movie             aMovie ;
  973.                                 MovieController    aController ;
  974.                                 DocumentHandle    aDocHdl ;
  975.                                 
  976.                                 aDocHdl = (DocumentHandle)GetWRefCon( whichWindow ) ;
  977.                                 aController = (**aDocHdl).myController ;
  978.                                 
  979.                                 aMovie = MCGetMovie( aController ) ;
  980.                         
  981.  
  982.                                 GetMovieBox(aMovie, &r);
  983.                                 screenRect = (**GetGrayRgn()).rgnBBox;
  984.                                 DragAlignedWindow(whichWindow, theEvent.where, &screenRect, &r, nil);
  985.                             }
  986.                             break;
  987.                             
  988.                         case inContent:
  989.                             
  990.                             HandleContentClick( whichWindow, &theEvent ) ;
  991.                             break ;
  992.                             
  993.                         case inGoAway:    
  994.  
  995.                             // if the window got closed, dispose of our movie 
  996.                             // and the controller and the window.
  997.                             
  998.                             if( TrackGoAway (whichWindow, theEvent.where ))
  999.                                 DoDestroyMovieWindow( whichWindow ) ;
  1000.                                 
  1001.                             break;
  1002.                     }
  1003.                     break ;
  1004.                     
  1005.                 case updateEvt:
  1006.                     
  1007.                     whichWindow = (WindowPtr)theEvent.message;                    
  1008.                     DoUpdateWindow( whichWindow ) ;
  1009.                     break;
  1010.                 
  1011.                 case keyDown:
  1012.                 case autoKey:
  1013.                     HandleKeyPress(&theEvent);
  1014.                     break;
  1015.                     
  1016.                 case diskEvt:
  1017.                     if ( HiWrd(theEvent.message) != noErr ) 
  1018.                         (void) DIBadMount(aPoint, theEvent.message);
  1019.                     break;
  1020.                     
  1021.                 case activateEvt:
  1022.                     // so are we becoming active?
  1023.                     whichWindow = (WindowPtr)theEvent.message ;
  1024.                     if( IsAppWindow(whichWindow)) {
  1025.                         DoActivateWindow( whichWindow, ((theEvent.modifiers & activeFlag) != 0)) ;
  1026.                     }
  1027.                     break;
  1028.  
  1029.                 case osEvt:
  1030.                     switch ((theEvent.message >> 24) & 0x00FF) {        // High byte of message
  1031.                         case suspendResumeMessage:
  1032.                             if (FrontWindow()) {
  1033.                                 DoActivateWindow(FrontWindow(), !((theEvent.message & resumeFlag) == 0));    
  1034.                             }
  1035.                             break;
  1036.  
  1037.                         case mouseMovedMessage:
  1038.                             break;
  1039.                     }
  1040.                     break;
  1041.                     
  1042.                 case kHighLevelEvent:                        // Let the Apple Event Manager handle high level event.
  1043.                     AEProcessAppleEvent(&theEvent);
  1044.                     break;
  1045.  
  1046.             }
  1047.         }
  1048.     }
  1049. }
  1050.  
  1051. //---------------------------------------------------------------------
  1052.  
  1053. Boolean IsAppWindow(WindowPtr window)
  1054. {
  1055.     short        windowKind;
  1056.  
  1057.     if ( window == nil )
  1058.         return false;
  1059.     else {
  1060.         windowKind = ((WindowPeek) window)->windowKind;
  1061.         return ((windowKind >= userKind) || (windowKind == dialogKind));
  1062.     }
  1063. }
  1064.  
  1065. //---------------------------------------------------------------------
  1066.  
  1067. // this handles posting the find dialog
  1068. void DoFindDialog( WindowPtr theMovieWindow, Point theMouse, ControlHandle aControl ) 
  1069. {
  1070.     DialogPtr        theFindDialog ;
  1071.     short            itemHit ;
  1072.     short            iType ;
  1073.     Handle            iHandle ;
  1074.     Rect            iRect ;
  1075.     Track            aTrack ;
  1076.     MediaHandler    aMediaHandler ;
  1077.     Movie            aMovie ;
  1078.     
  1079.     if( TrackControl(aControl, theMouse, nil ) != 0 ) {
  1080.     
  1081.         // get the find dialog
  1082.         theFindDialog = GetNewDialog(129, nil, (WindowPtr)-1 ) ;
  1083.         
  1084.         // set the default item, cancel item, and signal this has a TE field
  1085.         SetDialogDefaultItem( theFindDialog, 1 ) ;
  1086.         SetDialogCancelItem( theFindDialog, 2 ) ;
  1087.         SetDialogTracksCursor( theFindDialog, true ) ;
  1088.         
  1089.         // set up the default for the backwards search checkbox
  1090.         GetDItem ( theFindDialog, diBackwardsCheckBox, &iType, &iHandle, &iRect );
  1091.         SetCtlValue ( (ControlHandle)iHandle, gDlgSearchBack ) ;
  1092.  
  1093.         // set up the default for the wrap search checkbox
  1094.         GetDItem ( theFindDialog, diWrapCheckBox, &iType, &iHandle, &iRect );
  1095.         SetCtlValue ( (ControlHandle)iHandle, gDlgSearchWrap ) ;
  1096.  
  1097.         // and restore and setting we had for the search string
  1098.         GetDItem ( theFindDialog, diTextBox, &iType, &iHandle, &iRect );
  1099.         SetIText ( iHandle, gDlgSearchText );
  1100.         SelIText ( theFindDialog, diTextBox, 0, 32767 );    
  1101.                 
  1102.         do {
  1103.         
  1104.             ModalDialog(nil, &itemHit) ;
  1105.             
  1106.             if( itemHit == diBackwardsCheckBox ) {
  1107.                 GetDItem ( theFindDialog, diBackwardsCheckBox, &iType, &iHandle, &iRect );
  1108.                 gDlgSearchBack = !gDlgSearchBack ;
  1109.                 SetCtlValue ( (ControlHandle)iHandle, gDlgSearchBack ) ;
  1110.             }
  1111.             else if( itemHit == diWrapCheckBox ) {
  1112.                 GetDItem ( theFindDialog, diWrapCheckBox, &iType, &iHandle, &iRect );
  1113.                 gDlgSearchWrap = !gDlgSearchWrap ;
  1114.                 SetCtlValue ( (ControlHandle)iHandle, gDlgSearchWrap ) ;
  1115.             }
  1116.         } while( itemHit != ok && itemHit != cancel) ;
  1117.         
  1118.         if( itemHit == ok ) {
  1119.             // process the result
  1120.             GetDItem ( theFindDialog, diTextBox, &iType, &iHandle, &iRect );
  1121.             GetIText ( iHandle, gDlgSearchText );
  1122.         }
  1123.         
  1124.         // and dispose of the dialog
  1125.         DisposDialog ( theFindDialog );
  1126.         
  1127.         // if we hit cancel or if the user blanked out the text and hit return
  1128.         // return, we don't want to search.  If the user did blank it out
  1129.         // then beep.
  1130.         if( itemHit != ok || gDlgSearchText[0] == '\0') {
  1131.             if( gDlgSearchText[0] == '\0' )
  1132.                 SysBeep( 10 ) ;
  1133.             return ;
  1134.         }
  1135.         
  1136.     }
  1137.     else
  1138.         return ;
  1139.         
  1140.     // if we are here it is safe to assume that we have text to search for
  1141.     // get the movie reference from the window.
  1142.     
  1143.     // do the search
  1144.     DoSearchForStringInMovieWindow( theMovieWindow, gDlgSearchText, gDlgSearchBack, gDlgSearchWrap) ;
  1145.  
  1146. }
  1147.  
  1148. //---------------------------------------------------------------------
  1149.  
  1150. void DoSearchForStringInMovieWindow( WindowPtr theMovieWindow, 
  1151.                                      Str255 SearchText, 
  1152.                                      Boolean searchBack,
  1153.                                      Boolean searchWrap) 
  1154. {
  1155.     Movie             aMovie ;
  1156.     Track            aTrack ;
  1157.     MediaHandler    aMediaHandler ;
  1158.     MovieController    aController ;
  1159.     DocumentHandle    aDocHdl ;
  1160.     
  1161.     aDocHdl = (DocumentHandle)GetWRefCon( theMovieWindow ) ;
  1162.     aController = (**aDocHdl).myController ;
  1163.     
  1164.     aMovie =     MCGetMovie( aController ) ;
  1165.     
  1166.     if((aTrack = GetFirstTrackOfType( aMovie, TextMediaType )) != nil )
  1167.     {
  1168.         CheckError( GetMoviesError(), "\pfailed after GetFirstTrackOfType");
  1169.         aMediaHandler = GetMediaHandler( GetTrackMedia( aTrack ) ) ;
  1170.         
  1171.         CheckError( GetMoviesError(), "\pfailed after GetMediaHandler");
  1172.  
  1173.         if( aMediaHandler != nil ) {
  1174.             long        searchFlags ;
  1175.             TimeValue    startTime = 0, 
  1176.                         foundTime,
  1177.                         foundDuration ;
  1178.             long        offset ;
  1179.             TimeRecord    newTime ;
  1180.             RGBColor    highlightColor ;
  1181.             
  1182.             if(searchBack)
  1183.                 searchFlags = findTextReverseSearch ;
  1184.             else
  1185.                 searchFlags = 0L ;
  1186.                 
  1187.             if(searchWrap)
  1188.                 searchFlags = searchFlags | findTextWrapAround ;
  1189.                 
  1190.             CheckError( FindNextText(    aMediaHandler,
  1191.                             (Ptr)(&SearchText[1]),
  1192.                             SearchText[0],
  1193.                             searchFlags,
  1194.                             GetMovieTime( aMovie, nil ), 
  1195.                             &foundTime,
  1196.                             &foundDuration,
  1197.                             &offset ), "\pFindNextText failed"); ;
  1198.         
  1199.             if(foundTime != -1) {
  1200.                 // we need to convert the timevalue to a time record.
  1201.                 newTime.value.hiLong = 0 ;
  1202.                 newTime.value.loLong = foundTime ;
  1203.                 newTime.scale = GetMovieTimeScale( aMovie ) ;
  1204.                 newTime.base = nil ;
  1205.                             
  1206.                 // tell the movie to go to this time    
  1207.                 MCDoAction(aController, mcActionGoToTime, &newTime);
  1208.  
  1209.                 // highlight the text
  1210.                 highlightColor = (**((GrafVars **)((CGrafPtr)theMovieWindow)->grafVars)).rgbHiliteColor;
  1211.  
  1212.                 HiliteTextSample(    aMediaHandler, 
  1213.                                     foundTime, 
  1214.                                     offset,
  1215.                                     offset + SearchText[0], 
  1216.                                     &highlightColor);
  1217.  
  1218.             }
  1219.         }
  1220.     }
  1221. }
  1222.  
  1223.  
  1224. //---------------------------------------------------------------------
  1225.  
  1226. void AdjustMenus( void ) 
  1227. {
  1228.     WindowPtr            theWindow;
  1229.     MenuHandle            menu;
  1230.     long                offset;
  1231.     Boolean                undo;
  1232.     Boolean                cutCopyClear;
  1233.     Boolean                paste;
  1234.     TEHandle            te;
  1235.     MovieController        aController = nil ;
  1236.     DocumentHandle        aDocHdl = nil;
  1237.  
  1238.  
  1239.  
  1240.     if((theWindow = FrontWindow()) != nil ) {
  1241.         aDocHdl = (DocumentHandle)GetWRefCon(theWindow) ;
  1242.         aController = (**aDocHdl).myController ;
  1243.     }
  1244.     
  1245.     menu =     GetMHandle ( mFile ) ;
  1246.     if( theWindow != nil ) {
  1247.         EnableItem ( menu, iClose );
  1248.         EnableItem ( menu, iSaveAs );
  1249.     }
  1250.     else {
  1251.         DisableItem ( menu, iClose );
  1252.         DisableItem ( menu, iSaveAs );
  1253.     }
  1254.     
  1255.     menu = GetMHandle(mEdit);
  1256.     
  1257.     if( theWindow == nil || aController == nil || aDocHdl == nil) {
  1258.         DisableItem ( menu, 0 );
  1259.     }
  1260.     else if( (**aDocHdl).myMovieIsActive) {
  1261.         // is the movie the frontmost item
  1262.         // then let the movie controller set the menus up
  1263.         
  1264.         // this is done with MCSetUpEditMenu in the main event loop
  1265.         EnableItem( menu, 0 );
  1266.         
  1267.     }
  1268.     else {
  1269.     
  1270.         undo = false;
  1271.         cutCopyClear = false;
  1272.         paste = false;
  1273.         
  1274.         if ( IsDAWindow(theWindow) ) {
  1275.         
  1276.             undo = true;                // all editing is enabled for DA windows
  1277.             cutCopyClear = true;
  1278.             paste = true;
  1279.             
  1280.         } else if ( IsAppWindow(theWindow) ) {
  1281.         
  1282.             te = (**aDocHdl).myTEH ;
  1283.             if ( (*te)->selStart < (*te)->selEnd )
  1284.                 cutCopyClear = true;
  1285.                 
  1286.             // Cut, Copy, and Clear is enabled for app. windows with selections
  1287.             if ( GetScrap(nil, 'TEXT', &offset)  > 0)
  1288.                 paste = true;            // if there’s any text in the clipboard, paste is enabled
  1289.         }
  1290.         if ( undo )
  1291.             EnableItem(menu, iUndo);
  1292.         else
  1293.             DisableItem(menu, iUndo);
  1294.         if ( cutCopyClear ) {
  1295.             EnableItem(menu, iCut);
  1296.             EnableItem(menu, iCopy);
  1297.             EnableItem(menu, iClear);
  1298.         } else {
  1299.             DisableItem(menu, iCut);
  1300.             DisableItem(menu, iCopy);
  1301.             DisableItem(menu, iClear);
  1302.         }
  1303.         if ( paste )
  1304.             EnableItem(menu, iPaste);
  1305.         else
  1306.             DisableItem(menu, iPaste);
  1307.     }
  1308. }
  1309.  
  1310.  
  1311. //---------------------------------------------------------------------
  1312.  
  1313. void HandleKeyPress(EventRecord *event)
  1314. {
  1315.     char            key;
  1316.     DocumentHandle    aDocHdl ;
  1317.     TEHandle        myTEHdl ;
  1318.     WindowPtr        aWindow ;
  1319.     GrafPtr            savedPort ;
  1320.  
  1321.     key = event->message & charCodeMask;
  1322.         
  1323.     if ( event->modifiers & cmdKey ) {        /* Command key down? */
  1324.         AdjustMenus() ;
  1325.         HandleMenuCommand(MenuKey(key));
  1326.     } 
  1327.     else {
  1328.         if((aWindow = FrontWindow()) != nil ) {
  1329.             
  1330.             GetPort( &savedPort ) ;
  1331.             SetPort( aWindow ) ;
  1332.             
  1333.             // get the document handle
  1334.             if( (aDocHdl = (DocumentHandle)GetWRefCon(aWindow)) == nil )
  1335.                 return ;
  1336.                 
  1337.             // check the text edit field is active, if not beep and return
  1338.             if( (**aDocHdl).myMovieIsActive == true ) {
  1339.                 SysBeep( 10 );
  1340.                 return ;
  1341.             }
  1342.             
  1343.             // get the teh
  1344.             if((myTEHdl = (**aDocHdl).myTEH) == nil)
  1345.                 return ;
  1346.         
  1347.             // let textedit process the keydown
  1348.             TEKey( key, myTEHdl);
  1349.             
  1350.             // and signal that the text has changed
  1351.             if( !(**aDocHdl).myTextHasBeenModified ) {
  1352.                 Rect    theControlRect ;
  1353.                 
  1354.                 (**aDocHdl).myTextHasBeenModified = true ;
  1355.                 
  1356.                 // make the control redraw by invalidating it's rect
  1357.                 theControlRect = (**((**aDocHdl).myUpdateButton)).contrlRect ;
  1358.                 InvalRect( &theControlRect ) ;
  1359.             }
  1360.                 
  1361.             SetPort( savedPort ) ;
  1362.         }
  1363.     }
  1364. }
  1365.  
  1366.  
  1367. //---------------------------------------------------------------------
  1368.  
  1369. void HandleMenuCommand(long menuResult)
  1370. {
  1371.     short                menuID;
  1372.     short                menuItem;
  1373.     Str255                daName;
  1374.     DialogPtr            theDialog ; 
  1375.     short                itemHit ;
  1376.     FSSpec                theFile ;
  1377.     OSErr                err ;
  1378.     short                theRef ;
  1379.     
  1380.     Movie                aMovie = nil;
  1381.     MovieController        aController ;
  1382.     
  1383.     StandardFileReply    theSFReply ;
  1384.     DocumentHandle        aDocHdl ;
  1385.     WindowPtr            aWindow ;
  1386.     OSErr                theErr ;
  1387.     
  1388.     
  1389.     menuID = HiWrd(menuResult);
  1390.     menuItem = LoWrd(menuResult);
  1391.     switch ( menuID ) {
  1392.         case mApple:
  1393.             switch ( menuItem ) {
  1394.                 case iAbout:
  1395.                     theDialog = GetNewDialog ( 128, nil, (WindowPtr)-1 );
  1396.                     SetDialogDefaultItem(theDialog, 1) ;
  1397.  
  1398.                     do {
  1399.                         ModalDialog ( nil, &itemHit );
  1400.                     } while( itemHit != ok ) ;
  1401.                     DisposDialog ( theDialog );
  1402.                     break;
  1403.                     
  1404.                 default:
  1405.                     GetItem(GetMHandle(mApple), menuItem, daName);
  1406.                     (void) OpenDeskAcc(daName);
  1407.                     break;
  1408.             }
  1409.             break;
  1410.             
  1411.         case mFile:
  1412.             switch ( menuItem ) {
  1413.                 case iOpen:
  1414.  
  1415.                     // get the movie to open
  1416.                     
  1417.                     if(GetAMovieFileSpec(&theFile)) {
  1418.                         SendOpenDoc(&theFile) ;
  1419.                     }
  1420.  
  1421.                     break ;
  1422.                     
  1423.                 case iClose:
  1424.                     DoDestroyMovieWindow( FrontWindow() ) ;
  1425.                     break ;
  1426.                     
  1427.                 case iSaveAs:
  1428.  
  1429.  
  1430.                     // get the name of the file to save as
  1431.                     StandardPutFile("\pSave movie as:", "\pNew Movie File", &theSFReply) ;
  1432.                     
  1433.                     if( theSFReply.sfGood ) {
  1434.                     
  1435.                         // get the movie for this window
  1436.                         aDocHdl = (DocumentHandle)GetWRefCon( FrontWindow() ) ;
  1437.                         aController = (**aDocHdl).myController ;
  1438.                     
  1439.                         if( aController != nil ) {
  1440.                             aMovie = MCGetMovie( aController ) ;
  1441.                         }
  1442.                         else {
  1443.                             CheckError( -1, "\pCouldn't get movie controller") ;
  1444.                         }
  1445.                         
  1446.                         if( aMovie != nil ) {
  1447.                             
  1448.                             FlattenMovieData( aMovie, flattenAddMovieToDataFork, &theSFReply.sfFile, 'TVOD', smSystemScript, createMovieFileDeleteCurFile ) ;
  1449.  
  1450.                             theErr = GetMoviesError() ;
  1451.                             CheckError( theErr, "\pCouldn't FlattenMovieData") ;
  1452.                             
  1453.                         }
  1454.                         
  1455.                     }
  1456.                     break ;
  1457.                     
  1458.                  case iQuit:
  1459.                     SendQuitApp() ;        // send ourselves a quit event
  1460.                     break;
  1461.             }
  1462.             break;
  1463.             
  1464.         case mEdit:
  1465.         
  1466.             if((aWindow = FrontWindow()) != nil ) {
  1467.                 aDocHdl = (DocumentHandle)GetWRefCon(aWindow) ;
  1468.                 aController = (**aDocHdl).myController ;
  1469.             }
  1470.             
  1471.             // is the movie the current item, or is the textedit field current
  1472.             if((**aDocHdl).myMovieIsActive) {
  1473.  
  1474.                 // the movie is active so we use the movie controller 
  1475.                 // cut and paste commands
  1476.     
  1477.                 switch ( menuItem ) {
  1478.                 
  1479.                     case iUndo:
  1480.                         MCUndo( aController ) ;
  1481.                         break ;
  1482.                         
  1483.                     case iCut:
  1484.                         aMovie = MCCut( aController ) ;
  1485.                         break ;
  1486.                         
  1487.                     case iCopy:
  1488.                         aMovie = MCCopy( aController ) ;
  1489.                         break ;
  1490.                         
  1491.                     case iPaste:
  1492.                         MCPaste( aController, nil ) ;
  1493.                         break ;
  1494.                         
  1495.                     case iClear:
  1496.                         MCClear( aController ) ;
  1497.                         break ;
  1498.                         
  1499.                     case iSelectAll:
  1500.                         break ;
  1501.                 }
  1502.                 if( aMovie ) {
  1503.                     PutMovieOnScrap( aMovie, 0) ;
  1504.                     DisposeMovie( aMovie ) ;
  1505.                 }
  1506.             }
  1507.             else {
  1508.                 GrafPtr        savedPort ;
  1509.  
  1510.                 GetPort(&savedPort) ;
  1511.                 SetPort( (GrafPtr)aWindow ) ;
  1512.  
  1513.                 // the textedit field is active - handle cut and paste
  1514.  
  1515.                 if ( !SystemEdit(menuItem-1) ) {
  1516.                 
  1517.                     TEHandle te = (**aDocHdl).myTEH;
  1518.                     
  1519.                     switch ( menuItem ) {
  1520.                     
  1521.                         case iCut:
  1522.                             if ( (theErr = ZeroScrap()) == noErr ) {
  1523.                                 TECut(te);
  1524.                                 if ( (theErr = TEToScrap()) != noErr ) {
  1525.                                     ZeroScrap();
  1526.                                 }
  1527.                             }
  1528.                             (**aDocHdl).myTextHasBeenModified = true ;
  1529.                             CheckError(theErr, "\pCan't perform textEdit cut operation" ) ;
  1530.                             break;
  1531.                             
  1532.                         case iCopy:
  1533.                             if ( (theErr = ZeroScrap()) == noErr ) {
  1534.                                 TECopy(te);    // after copying, export the TE scrap 
  1535.                                 if ( (theErr = TEToScrap()) != noErr ) {
  1536.                                     ZeroScrap();
  1537.                                 }
  1538.                             }
  1539.                             CheckError(theErr, "\pCan't perform textEdit copy operation" ) ;
  1540.                             break;
  1541.                             
  1542.                         case iPaste:    // import the TE scrap before pasting
  1543.                             if ( (theErr = TEFromScrap()) == noErr ) {
  1544.                                 if ( !(TEGetScrapLen() + ((*te)->teLength - ((*te)->selEnd - (*te)->selStart)) > 32000 )) {
  1545.                                     Handle         aHandle = (Handle) TEGetText(te);
  1546.                                     short         oldSize = GetHandleSize(aHandle);
  1547.  
  1548.                                     // allow 1k slop in the newSize to make textEdit happy
  1549.                                     short         newSize = oldSize + TEGetScrapLen() + 1024;
  1550.                                     SetHandleSize(aHandle, newSize);
  1551.                                     theErr = MemError();
  1552.                                     SetHandleSize(aHandle, oldSize);
  1553.                                     if (theErr == noErr)
  1554.                                         TEStylPaste(te);
  1555.                                 }
  1556.                             }
  1557.                             (**aDocHdl).myTextHasBeenModified = true ;
  1558.                             CheckError(theErr, "\pCan't perform textEdit paste operation" ) ;
  1559.                             break;
  1560.                             
  1561.                         case iClear:
  1562.                             TEDelete(te);
  1563.                             (**aDocHdl).myTextHasBeenModified = true ;
  1564.                             break;
  1565.                     }
  1566.                 }
  1567.                 if((**aDocHdl).myTextHasBeenModified) {
  1568.                     InvalRect( &((GrafPtr)aWindow)->portRect ) ;
  1569.                 }
  1570.                 SetPort( savedPort ) ;
  1571.             }
  1572.             break ;
  1573.             
  1574.     }
  1575.     HiliteMenu(0);        // Unhighlight whatever MenuSelect or MenuKey hilited
  1576. }
  1577.  
  1578. //---------------------------------------------------------------------
  1579.  
  1580. void InitMac( void )
  1581. {
  1582.     Handle        menuBar = nil;
  1583.  
  1584.     // we want to grow the heap as big as possble, or the text media handler may not 
  1585.     // load the text track properly initially
  1586.  
  1587.     MaxApplZone();
  1588.     MoreMasters(); MoreMasters(); MoreMasters(); MoreMasters();
  1589.     MoreMasters(); MoreMasters(); MoreMasters(); MoreMasters();
  1590.     MoreMasters(); MoreMasters(); MoreMasters(); MoreMasters();
  1591.     MoreMasters(); MoreMasters(); MoreMasters(); MoreMasters();
  1592.  
  1593.     InitGraf (&qd.thePort);
  1594.     InitFonts ();
  1595.     InitWindows ();
  1596.     InitMenus ();
  1597.     TEInit ();
  1598.     InitDialogs ((long)nil);
  1599.     
  1600.     if (!IsQuickTimeInstalled()) {
  1601.         CheckError(-1,"\pPlease install QuickTime and try again.");
  1602.     }
  1603.     
  1604.     CheckError( EnterMovies (), "\pEnterMovies failed" );    
  1605.     
  1606.     // get the menu bar
  1607.         
  1608.     menuBar = GetNewMBar(128);                // Read menus into menu bar, MBAR res id is 128
  1609.     
  1610.     if ( menuBar == nil )
  1611.          ExitToShell();                        // if we dont have it then quit - your app 
  1612.                                              // needs a dialog here
  1613.  
  1614.     SetMenuBar(menuBar);                    // Install menus
  1615.     DisposHandle(menuBar);
  1616.     
  1617.     AddResMenu(GetMHandle(mApple), 'DRVR');    // Add DA names to Apple menu, ID 128
  1618.  
  1619.     DrawMenuBar();
  1620.  
  1621.     
  1622.     gQuitFlag = false ;                    // set the flag for the main event loop
  1623. }
  1624.  
  1625.  
  1626. //---------------------------------------------------------------------
  1627.  
  1628. void DoDrawCurrentText( WindowPtr theWindow ) 
  1629. {
  1630.     GrafPtr            savedPort ;
  1631.     Rect            theRect;
  1632.     short            h, v ;
  1633.     RGBColor        savedFore, savedBack ;
  1634.     DocumentHandle    aDocHdl ;
  1635.     char            cMemTags ;
  1636.     TEHandle        aDocTEH ;
  1637.  
  1638.     GetPort( &savedPort ) ;
  1639.     SetPort( (GrafPtr)theWindow ) ;
  1640.     
  1641.     aDocHdl = (DocumentHandle)GetWRefCon( theWindow ) ;
  1642.     
  1643.     if(aDocHdl == nil)
  1644.         return ;
  1645.         
  1646.     aDocTEH = (**aDocHdl).myTEH ;
  1647.     theRect = (**aDocTEH).viewRect ;
  1648.     TEUpdate( &theRect, aDocTEH ) ;
  1649.         
  1650.     // reset the port
  1651.     SetPort( savedPort ) ;
  1652. }
  1653.  
  1654.  
  1655.  
  1656. //---------------------------------------------------------------------
  1657.  
  1658. pascal OSErr MyTextProc(    Handle         thisText, 
  1659.                             Movie         thisMovie, 
  1660.                             short         *displayFlag,
  1661.                             long         refcon)            // contains a ref to the window for this movie
  1662. {
  1663.     long            totalSampleSize ; 
  1664.     char            *samplePtr = nil ;
  1665.     char            *stylePtr = nil;
  1666.     char            *textPtr = nil;
  1667.  
  1668.     short            sampleSize ;
  1669.     short            styleSize ;
  1670.     short            textSize ;
  1671.  
  1672.     StScrpHandle    scrapHdl = nil;
  1673.     DocumentHandle    aDocHdl = nil;
  1674.     TEHandle        myDocTEH = nil;
  1675.     GrafPtr            savedPort ;
  1676.     Rect            aRect ;
  1677.     OSType            atomType ;
  1678.  
  1679.     char            thisTextState ;
  1680.     SampleDescriptionHandle            sampleDescriptionH = (SampleDescriptionHandle)NewHandle( 0 ) ;
  1681.  
  1682.  
  1683.     thisTextState = HGetState( thisText ) ;
  1684.     HLock( thisText ) ;
  1685.         
  1686.     GetPort( &savedPort ) ;
  1687.     SetPort((WindowPtr)refcon) ;
  1688.     
  1689.     aDocHdl = (DocumentHandle)GetWRefCon((WindowPtr)refcon) ;
  1690.     if( aDocHdl == nil )
  1691.         return noErr ;
  1692.     
  1693.     myDocTEH = (**aDocHdl).myTEH ;
  1694.     
  1695.     // both the text and the style information are included in the handle
  1696.     // get the size of the handle and the size of the text    
  1697.     
  1698.     totalSampleSize = GetHandleSize(thisText);            // this is the size of the total handle
  1699.                                                         // which may contain styl information
  1700.                                                         
  1701.     textSize = *(short*)(*thisText);              // This will yield the actual size of the text
  1702.     textPtr = (char*)(*thisText + sizeof(short)); // yields a reference to the start of the text
  1703.  
  1704.  
  1705.     // get the default style for this sample
  1706.     {
  1707.         MovieController    aController ;
  1708.         Movie            aMovie ;
  1709.         Track            aTrack ;
  1710.         OSErr            theErr ;
  1711.         
  1712.         if((aController = (**aDocHdl).myController) != nil ) {
  1713.             if((aMovie = MCGetMovie( aController )) != nil ) {
  1714.     
  1715.                 // get the text media track
  1716.                 if((aTrack = GetFirstTrackOfType( aMovie, TextMediaType )) != nil )
  1717.                 {
  1718.                     
  1719.                     Media            aMedia ;
  1720.                     
  1721.                     TimeValue        currentTime ;
  1722.                     TimeValue        interestingTime ;
  1723.                     TimeValue        mediaCurrentTime ;
  1724.                     TimeValue        theDuration ;
  1725.         
  1726.                     Handle            myData = NewHandle( 0 ) ;
  1727.                     
  1728.                     CheckError( GetMoviesError(), "\pfailed after GetFirstTrackOfType");
  1729.                     aMedia =  GetTrackMedia( aTrack ) ;
  1730.                                     
  1731.                     // get the current movie time
  1732.                     currentTime = GetMovieTime( aMovie, nil ) ;
  1733.                     if( currentTime < 0 ) 
  1734.                         CheckError( -1, "\pthis is an empty edit") ;
  1735.                                                             
  1736.                     //  look back and find where this text starts
  1737.                     GetTrackNextInterestingTime( aTrack, nextTimeEdgeOK | nextTimeMediaSample, currentTime, 
  1738.                                         -kFix1, &interestingTime, nil  ) ;
  1739.                     
  1740.                     currentTime = interestingTime ;
  1741.                                 
  1742.                     GetTrackNextInterestingTime( aTrack, nextTimeEdgeOK | nextTimeMediaSample, currentTime, 
  1743.                                         kFix1, &interestingTime, &theDuration ) ;
  1744.  
  1745.                     mediaCurrentTime = TrackTimeToMediaTime( interestingTime, aTrack ) ;
  1746.  
  1747.                     // mediaSampleStartTime contains the start of this sample
  1748.                     theErr = GetMediaSample( aMedia,
  1749.                                              myData,
  1750.                                              0L,
  1751.                                              nil,
  1752.                                              mediaCurrentTime,
  1753.                                              nil,
  1754.                                              nil,
  1755.                                              sampleDescriptionH,
  1756.                                              nil,
  1757.                                              0L,
  1758.                                              nil,
  1759.                                              nil) ;
  1760.                 }
  1761.             }
  1762.         }
  1763.     }
  1764.  
  1765.     if( sampleDescriptionH ) {
  1766.         scrapHdl = (StScrpHandle)NewHandle(sizeof(StScrpRec)) ;
  1767.         if( scrapHdl == nil )
  1768.             CheckError(MemError(), "\pCouldn't allocate memory for the style table" ) ;
  1769.         (**scrapHdl).scrpNStyles = 1 ;
  1770.         (**scrapHdl).scrpStyleTab[0] = (**((TextDescriptionHandle)sampleDescriptionH)).defaultStyle ;
  1771.  
  1772.         // this next item will force the style run to be in the window's fg color, we
  1773.         // may not want to force this, so remove this if you want to use colored text.
  1774.         (**scrapHdl).scrpStyleTab[0].scrpColor = ((CGrafPtr)(**myDocTEH).inPort)->rgbFgColor;
  1775.  
  1776.  
  1777.         // delete the previous contents of the TEH
  1778.         TESetSelect( 0, (**myDocTEH).teLength, myDocTEH );
  1779.         TEDelete( myDocTEH ) ;
  1780.  
  1781.         // insert the new text
  1782.         TEStylInsert( textPtr, textSize, scrapHdl, myDocTEH );
  1783.  
  1784.         DisposHandle((Handle)scrapHdl) ;
  1785.     }
  1786.     else {
  1787.         TESetText( textPtr, textSize, myDocTEH ) ;
  1788.     }
  1789.     // additional style information is in the format of a TE Style Scrap Record
  1790.     // there is other information here too.  If there is more information
  1791.     // to get, then it will be appended as atoms.  we will know that there 
  1792.     // is more to look at if the size of the total sample is larger than the 
  1793.     // size of the text sample.
  1794.     //
  1795.     // Each atom is 
  1796.     //    Atom Size - long (4bytes).  This includes the size and type fields
  1797.     //     Atom Type - OSType (4 Bytes)
  1798.     if( totalSampleSize > (textSize + sizeof(short))) {
  1799.  
  1800.         // step through whatever is in the handle
  1801.  
  1802.         for( samplePtr = (*thisText) + (textSize + sizeof(short)) ;        // start at the atom after the text
  1803.              (samplePtr - (*thisText)) < totalSampleSize ;                // make sure that we don't go off the end
  1804.              samplePtr += sampleSize )                                    // bump up the pointer
  1805.         {
  1806.             // get the sample size and do the best we can to validate with it
  1807.             if((sampleSize = *((long *) samplePtr)) < 0 || sampleSize > totalSampleSize)  break;
  1808.             atomType = *((long *)(samplePtr + sizeof( long ))) ;
  1809.             
  1810.             // the only one we are interested in is the 'styl' atom
  1811.             // other types exist:
  1812.             // 'tbox' - shrunken text box atom
  1813.             // 'hlit' - highlighting atom
  1814.             // 'dlay' - scroll delay
  1815.             // 'hclr' - highlight color
  1816.             // see page 2-290 of Inside Macintosh: QuickTime for details
  1817.  
  1818.             switch( atomType ) {
  1819.  
  1820.                 case 'styl':
  1821.                     styleSize = sampleSize - (2*sizeof(long)) ;
  1822.                     stylePtr = samplePtr +  (2*sizeof(long)) ;
  1823.                     scrapHdl = (StScrpHandle)NewHandle(styleSize);
  1824.  
  1825.                     if (MemError() != noErr || scrapHdl == nil)
  1826.                         return;
  1827.         
  1828.                     BlockMove(stylePtr, *scrapHdl, styleSize);
  1829.                     
  1830.                     // and apply the style to the TERec
  1831.                     SetStylScrap( 0, 32767, scrapHdl, false, myDocTEH ) ;
  1832.  
  1833.                     break ;
  1834.  
  1835.                 default:
  1836.                     // you could parse the other types here
  1837.                     break ;
  1838.  
  1839.             }
  1840.         }
  1841.     }
  1842.  
  1843.     // Invalidate the area of the TEH
  1844.     
  1845.     aRect = (**myDocTEH).viewRect ;
  1846.     InvalRect( &aRect ) ;
  1847.     // invalidate the control and set it so it is not enabled
  1848.     
  1849.     aRect = (**(**aDocHdl).myUpdateButton).contrlRect ;
  1850.     InvalRect( &aRect ) ;
  1851.     
  1852.     // disable the control
  1853.     (**aDocHdl).myTextHasBeenModified = false ;
  1854.     
  1855.     // just display whatever we would do on the movie
  1856.     *displayFlag = txtProcDefaultDisplay;
  1857.     
  1858.     HSetState(thisText,thisTextState);
  1859.     
  1860.     SetPort(savedPort) ;
  1861.          
  1862. }
  1863.  
  1864. //---------------------------------------------------------------------
  1865. // main - entry point for the app.
  1866.  
  1867. void main (void)
  1868. {
  1869.     // initialise the managers
  1870.     InitMac() ;
  1871.  
  1872.     // initialise the appleevent hadlers
  1873.     InitAEStuff() ;
  1874.     RegisterMyEvents() ;
  1875.  
  1876.     // run 'til we die…
  1877.     MainEventLoop() ;
  1878. }
  1879.  
  1880. // command handlers
  1881.  
  1882. //-----------------------------------------------------------------------
  1883. // we don't do this, so tell whoever called us by returning 
  1884. // errAEEventNotHandled
  1885.  
  1886. OSErr HandlePrintDoc( FSSpec *myFSS )
  1887. {                    
  1888.     return errAEEventNotHandled ;    
  1889. }
  1890.  
  1891. //-----------------------------------------------------------------------
  1892.  
  1893. OSErr HandleOpenDoc( FSSpec *myFSS )
  1894. {                    
  1895.     Movie         aMovie = nil;
  1896.     short         movieResFile;
  1897.     short         movieResID = 0;        // want the first movie in the file
  1898.     Str255         movieName;
  1899.     Boolean     wasChanged;
  1900.     
  1901.     // attempt to open the movie file, and create a window
  1902.     OSErr        err = OpenMovieFile (myFSS, &movieResFile, fsRdPerm );
  1903.  
  1904.     if (err == noErr) {
  1905.         err = NewMovieFromFile (&aMovie, movieResFile,
  1906.                                          &movieResID,
  1907.                                         movieName, 
  1908.                                         newMovieActive,        // flags
  1909.                                         &wasChanged);
  1910.         CloseMovieFile (movieResFile);
  1911.         if(err == noErr )
  1912.             DoCreateMovieWindow( aMovie ) ;
  1913.     }
  1914.  
  1915.     return err ;
  1916. }
  1917.  
  1918.